/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace CsJni
{
    public sealed class JniConstructor : JniMember
    {
        public const string JniConstructorName = "<init>";

        internal JniConstructor(IntPtr handle, JniClass declaringClass, string signature)
            : base(handle, declaringClass, false, signature)
        {
        }

        // NOTE: Cannot be used for array types, use NewBooleanArray, etc.
        // Cannot be used for String, use NewString.
        // Cannot be used for Class, because Class is abstract and thus cannot be constructed.
        // For Throwable, use NewThrowableObject.
        public JniObject NewObject(JniEnvironment environment, JValue[] arguments)
        {
            return NewObjectCore(environment, arguments, JniConcreteObjectType.Object);
        }

        public JniObject NewThrowableObject(JniEnvironment environment, JValue[] arguments)
        {
            return NewObjectCore(environment, arguments, JniConcreteObjectType.Throwable);
        }

        public JniObject NewObjectCore(JniEnvironment environment, JValue[] arguments, JniConcreteObjectType concreteType)
        {
            VerifyEnvironment(environment);
            // NOTE: OK if "JValue[] arguments" is null
            IntPtr result = JniEnvironment.Functions.NewObjectA(environment.Handle, this.DeclaringClass.Handle, this.Handle, arguments);
            if (IntPtr.Zero == result)
            {
                JniThrowable.ThrowCurrentException(environment); // null result means an exception occurred
            }
            // EXCEPTION CHECK: Do nothing, already checked for exception above.
            return JniObject.CreateObjectOfType(environment, result, concreteType);
        }
    }
}
